package com.ubb.dbms.core.fileManagers.dataFileManager;

import java.io.File;
import java.util.Map;

import com.ubb.dbms.core.fileManagers.indexFileManager.IndexFileManager;
import com.ubb.dbms.domain.queryData.TableRowElements;
import com.ubb.dbms.domain.queryResult.RawDataConverter;
import com.ubb.dbms.domain.queryResult.SelectedRow;
import com.ubb.dbms.domain.xml.IndexFile;
import com.ubb.dbms.domain.xml.Table;


public class DataFileManagerImpl implements DataFileManager {

	public DataFileManagerImpl() {
		DataFileIO dataFileIO = new DataFileIO();
		dataFileIO.createDirectoryIfNotExists(DATABASES_FOLDER_NAME);
	}

	@Override
	public void createFolderForDatabase(String databaseName) {
		DataFileIO dataFileIO = new DataFileIO();
		dataFileIO.createDirectoryIfNotExists(DATABASES_FOLDER_NAME + databaseName);
	}

	@Override
	public void createFileForTable(Table table, String usesDatabase) {
		// building the partial path for table and rows state table files
		String tableFileFolder = getTableFileFolder(usesDatabase, table.getTableName());
		String tableFilePath = getTableFilePath(tableFileFolder, table);
		String rsTableFilePath = getRsTableFilePath(tableFileFolder, table);
		// creates the files for the table
		new DataFileIO(tableFilePath, rsTableFilePath, 0, 0);
	}

	public static String getTableFileFolder(String usesDatabase, String tableName) {
		return DATABASES_FOLDER_NAME + usesDatabase + File.separator + tableName + File.separator;
	}

	public static String getTableFilePath(String tableFileFolder, Table table) {
		return tableFileFolder + table.getFileName();
	}

	public static String getRsTableFilePath(String tableFileFolder, Table table) {
		return tableFileFolder + table.getTableName() + ROWS_STATES_DATA_FILES_EXTENSION;
	}

	@Override
	public int insertRow(TableRowElements rowElements, Table table, String usesDatabase) {
		// building the partial path for table and rows state table files
		String tableFileFolder = getTableFileFolder(usesDatabase, table.getTableName());
		String tableFilePath = getTableFilePath(tableFileFolder, table);
		String rsTableFilePath = getRsTableFilePath(tableFileFolder, table);
		
		int rowLength = Integer.parseInt(table.getRowLenght());
		DataFileIO dataFileIO = new DataFileIO(tableFilePath, rsTableFilePath, 0, rowLength);
		int rowNr = dataFileIO.insertRow(rowElements, table);
		return rowNr;
	}

	@Override
	public void indexExistingTableData(IndexFile indexFile, Table table, String usesDatabase, IndexFileManager indexFileManager) {
		String columnName = indexFile.getIndexAttribute().getIndexAttributeList().get(0).getValue();
		String[] tableColumnProjection = new String[] {columnName};
		Map<String, String> tableColumnProjectionsMap = RawDataConverter.projectionArrayToMap(tableColumnProjection);
		DataFileParser dataFileParser = new DataFileParser(table, usesDatabase, tableColumnProjectionsMap);
		
		while (dataFileParser.hasNext()) {
			SelectedRow selectedRow = dataFileParser.next();
			Object key = selectedRow.getRowValue(columnName);
			indexFileManager.insertKey(key, dataFileParser.getRowNrCounter(), usesDatabase, table, indexFile);
		}
	}

	@Override
	public SelectedRow readRow(Table table, String usesDatabase, int rowNr) {
		return this.readRow(table, usesDatabase, rowNr, RawDataConverter.FULL_PROJECTION_MAP);
	}

	@Override
	public SelectedRow readRow(Table table, String usesDatabase, int rowNr, Map<String, String> projections) {
		String tableFileFolder = getTableFileFolder(usesDatabase, table.getTableName());
		String tableFilePath = getTableFilePath(tableFileFolder, table);
		String rsTableFilePath = getRsTableFilePath(tableFileFolder, table);
		int rowLength = Integer.parseInt(table.getRowLenght());
		DataFileIO dataFileIO = new DataFileIO(tableFilePath, rsTableFilePath, 0, rowLength);
		return dataFileIO.readRow(table, rowNr, projections);
	}
}
